package cn.itsource.org.service.Impl;

import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.itsource.basic.service.Impl.BaseSerivcelmpl;
import cn.itsource.basic.util.AjaxResult;
import cn.itsource.basic.util.RedisService;
import cn.itsource.basic.util.SendMessageService;
import cn.itsource.config.exception.BusinessException;
import cn.itsource.org.domain.User;
import cn.itsource.org.mapper.UserMapper;
import cn.itsource.org.query.UserQuery;
import cn.itsource.org.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
@Slf4j
//Propagation.SUPPORTS:支持别人事务
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public class UserServiceImpl extends BaseSerivcelmpl<User, UserQuery> implements UserService {
   @Autowired
    private UserMapper userMapper;
    @Autowired
    private RedisService redisService;
    @Autowired
    private SendMessageService sendMessageService;

    @Override
    public AjaxResult checkPhone(String phone) {
        //1.验证手机号合法性
        boolean mobile = Validator.isMobile(phone);
        if (!mobile){
            throw new BusinessException("手机号格式不对...");
        }
        //判断手机号是否存在
        User user = userMapper.selectPhone(phone);
        if (user != null){
            throw new BusinessException("用户已经注册..");
        }
        return AjaxResult.createSuccess("手机号验证通过");
    }

    @Override
    public AjaxResult sendMobileCode(String phone) {
        //1.验证手机号合法性
        boolean mobile = Validator.isMobile(phone);
        if (!mobile){
            throw new BusinessException("手机号格式不对...");
        }
        //判断手机号是否存在
        User user = userMapper.selectPhone(phone);
        if (user != null){
            throw new BusinessException("用户已经注册..");
        }
        //3.拦截同一个ip一直获取验证码  //
        /*String s = request.getRemoteAddr() + request.getRequestURI();
        int i = s.lastIndexOf("/");
        String ipPhoneStr = s.substring(0, i);

        String res = redisService.getKeyObjectValue(ipPhoneStr, String.class);
        if (res != null){ //如果redis里面有数据，代表你访问过于频繁
            throw new BusinessException("哥哥，你太快了...");
        }
        //存ip到redis中,保持1分钟,1分钟内重复获取抛出上面的异常
        redisService.setStringKeyAndValue(ipPhoneStr,phone,1);*/

        //4.生成验证码,保存到redis 5分钟
        String code = RandomUtil.randomNumbers(4);
        //phone:手机号  code:验证码
        redisService.setStringKeyAndValue(phone,code,5);
        log.info("[宠物乐园验证码]:{},手机号:{}",code,phone);

        //调用发送验证码的服务 打印知道存到redis里面的验证码就行了,不发送
        //sendMessageService.sendPhoneMessage(phone,"[宠物乐园验证码]:"+code);

        return AjaxResult.createSuccess("发送验证码成功");
    }

    @Override
    public AjaxResult register(User user) {
        //自己去比对两次密码

        //验证手机号
        boolean mobile = Validator.isMobile(user.getPhone());
        if (!mobile){
            throw new BusinessException("手机号有误,请重新输入...");
        }

        //2.校验手机号是否被注册过
        User dbUser = userMapper.selectPhone(user.getPhone());

        if (dbUser != null){
            throw new BusinessException("用户已经注册过了...");
        }
        //1.从redis里面获取验证码，如果获取不到，过期了
        String redisCode = redisService.getKeyStringValue(user.getPhone());

        //1.1没拿到异常
        /*if (StrUtil.isBlank(redisCode)){
            throw   new BusinessException("验证码过期了");
        } 这个是全写，下面是java8新写法 */
        Optional.ofNullable(redisCode).orElseThrow(() -> new BusinessException("验证码过期了"));

        //2.把你传递的验证码和redis里面比对，如果比对不过，代表验证码错误
        if (!StrUtil.equals(user.getCode(),redisCode)){
            throw new BusinessException("验证码错误...");
        }

        //3.入库 （注意：加盐加密）
        user.md5Pwd();
        userMapper.insertSelective(user);

        return AjaxResult.createSuccess();
    }
}
